package com.lemon.springcloud.core.component.zookeeper;

import com.lemon.core.conf.ZKClient;
import com.lemon.springcloud.core.config.LemonSpringBootConfig;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;

/**
 * Class Name: ZkClient
 * Create Date: 18-3-21 下午8:58
 * Creator: lemon
 * Version: v1.0
 * Updater:
 * Date Time:
 * Description:
 * <p>
 * TODO:初始化Zk
 * <p>
 * 设计目标:
 * 通过jvm参数获取默认的zk配置,提供配置方式,在yml中提供zk配置列表
 */
public class ZkBoot {

    private boolean initialized = false;

    private String zkAddress = null;

    private ZKClient zkClient = null;

    public ZkBoot() {
    }

    public ZkBoot(String zookeeperGroupName, String host, String port) {
        String zookeeperProtocol = "zookeeper://" + host + ":" + port;
        LemonSpringBootConfig.addZookeeperGroupInfo(zookeeperGroupName, zookeeperProtocol);
        this.zkAddress = host + ":" + port;
        init();
    }

    public String getZkAddress() {
        return zkAddress;
    }

    boolean isInitialized() {
        return initialized;
    }

    public interface ZkChangeCallback {

        void strValChanged(String val);

    }

    void setZkAddress(String zkAddress) {
        this.zkAddress = zkAddress;
    }

    void init() {
        this.zkClient = ZKClient.get(this.zkAddress);
        initialized = true;
    }

    public String getStrAndWatch(String path, ZkChangeCallback callback) {
        String data;
        try {
            data = zkClient.getStringData(path);
            if (callback != null) {
                zkClient.watchStrValueNode(path, new ZKClient.StringValueWatcher() {
                    @Override
                    public void valueChanged(String val) {
                        callback.strValChanged(val);
                    }
                });
            }
            return data;
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getStrAndWatch(String path) {
        return getStrAndWatch(path, null);
    }

    public boolean connected() {
        ZooKeeper.States state = zkClient.getZooKeeper().getState();
        return true;
    }

    public ZKClient getZkClient() {
        return zkClient;
    }

    public boolean createIfNotExists(String path) {
        try {
            zkClient.createIfNotExist(path);
            return true;
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }

    public boolean createIfNotExists(String path, CreateMode mode) {
        try {
            zkClient.createIfNotExist(path, mode);
            return true;
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }

    public boolean create(String path, byte[] data, CreateMode mode) {
        try {
            zkClient.create(path, data, mode);
            return true;
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }

    public boolean setData(final String path, final byte data[]) {
        try {
            zkClient.setData(path, data);
            return true;
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }

    public boolean delete(String path) {
        try {
            zkClient.forceDelete(path);
            return true;
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }
}
